package net.oschina.app.util;

import android.content.Context;
import android.os.Environment;
import android.os.SystemClock;
import android.support.v4.util.LruCache;
import android.text.TextUtils;

import com.jakewharton.disklrucache.DiskLruCache;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;

/**
 * Created by U on 2017/3/25.
 * 处理协议缓存
 */

public class CacheUtils {
    public final static int MEMORY_CAHCE_SIZE = 1024 * 1024 * 5;// 5M
    public final static int DISK_CAHCE_SIZE = 1024 * 1024 * 10;//10M
    public final static String UNIQUENAME = "heima14";
    public final static long DURATION_TIME = 1000 * 60 * 3;// 缓存时间3分钟
    private DiskLruCache mDiskLruCache;
    private LruCache<String, String> mMemoryCache;
    private PrintWriter mWriter;
    private OutputStream mOs;
    private BufferedWriter mBw;

    public CacheUtils() {
        // 1 内存的Lru
        mMemoryCache = new LruCache<String, String>(MEMORY_CAHCE_SIZE) {
            // 添加进的每一项是多少
            @Override
            protected int sizeOf(String key, String value) {
                return value.getBytes().length;
            }
        };
        // 2 创建磁盘的DiskLruCache
        //File directory, int appVersion, int valueCount, long maxSize
        File cacheDir = getDiskCacheDir(UIUtils.getContext(), UNIQUENAME);
        int appVersion = PackageUtlis.getVersionCode(UIUtils.getContext());
        int valueCount = 1;//第三个参数指定同一个key可以对应多少个缓存文件，基本都是传1
        //directory:缓存的路径
        //appVersion:应用版本号
        //valueCount:指定同一个key可以对应多少个缓存文件，基本都是传1
        // maxSize:缓存最大值
        try {
            mDiskLruCache = DiskLruCache.open(cacheDir, appVersion, valueCount, DISK_CAHCE_SIZE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 获取缓存目录： /sdcard/Android/data/<application package>/cache
    public File getDiskCacheDir(Context context, String uniqueName) {
        String cachePath;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            cachePath = context.getExternalCacheDir().getPath();
        } else {
            cachePath = context.getCacheDir().getPath();
        }
        return new File(cachePath + File.separator + uniqueName);
    }

    // 获取内存缓存数据
    public String getMemoryCache(String key) {
        return mMemoryCache.get(key);
    }

    // 存储内存缓存数据
    public void cacheToMemory(String key, String value) {
        mMemoryCache.put(key,value);
    }

    // 获取磁盘的缓存数据
    public String getLocalCache(String key) {
        // 1 获取SnapShot(快照)
        try {
            DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);
            if (snapshot != null) {
                DiskLruCache.Editor editor = snapshot.edit();
                if (editor != null) {
                    // 获取缓存文件的输入流
                    InputStream is = editor.newInputStream(0);

                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
                    // 首先知道第一存储是插入的时间
                    long cacheTime = Long.parseLong(br.readLine());
                    long currentTime = SystemClock.elapsedRealtime();
                    if ((currentTime - cacheTime) >= DURATION_TIME) {// 过期
                        br.close();
                        editor.commit();
                        return null;
                    }
                    // 没有过期
                    StringBuilder sb = new StringBuilder();
                    String temp;
                    while ((temp = br.readLine()) != null) {
                        sb.append(temp);
                    }
                    br.close();
                    // 存储到内存中
                    cacheToMemory(key, sb.toString());
                    editor.commit();
                    return sb.toString();
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    // 存储硬盘缓存数据
    public void cacheToLocal(String key, String value) {
        // 1 获取Editor
        try {
            DiskLruCache.Editor editor = mDiskLruCache.edit(key);
            mOs = editor.newOutputStream(0);
            //有了输出流

            mWriter = new PrintWriter(mOs);
            mBw = new BufferedWriter(mWriter);
            // 1 写第一行：插入时间
            long cacheTime = SystemClock.elapsedRealtime();// 开机时间该是算起
//                             System.currentTimeMillis();// January 1, 1970
            mBw.write(String.valueOf(cacheTime));// 换行
            mBw.newLine();
            // 2 接下来写内容
            mBw.write(value);
            mBw.flush();
            editor.commit();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.close(mOs);
            IOUtils.close(mWriter);
            IOUtils.close(mBw);
        }
    }

    // url:md值：json
    // 通用流程的加载
    public String getCache(String key) {
        //先从内存中获取，假如获取不到，再从磁盘中获取，磁盘中获取不到，返回null
        String cache = getMemoryCache(key);
        if (!TextUtils.isEmpty(cache)) {
            // 从内存中获取到
            LogUtils.d("从内存中获取到");
            return cache;
        }
        //假如获取不到，再从磁盘中获取
        cache = getLocalCache(key);
        if (!TextUtils.isEmpty(cache)) {
            // 从磁盘中获取到
            LogUtils.d("从磁盘中获取到");
            return cache;
        }
        return null;
    }

    // 保存到内存和硬盘中
    public void saveCache(String key, String result) {
        //保存内存
        cacheToMemory(key, result);
        //保存到本地
        cacheToLocal(key, result);
    }

}
